chore(typecheck): seven ledgered packages type-check their own tests through a sibling test program (#12511) - #16295
Merged
baozhoutao merged 3 commits intoSep 6, 2026
Conversation
…gered packages WIP: the tsconfig.test.json files and the package.json wiring. Ledgers, the TEST_DEBT graduations and the config headers follow in the next commits. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
…and config headers Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
…st-typecheck-sibling-configs
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 23 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
This was referenced Sep 6, 2026
baozhoutao
marked this pull request as ready for review
September 6, 2026 13:17
baozhoutao
enabled auto-merge
September 6, 2026 13:17
baozhoutao
deleted the
claude/issue-12511-test-typecheck-sibling-configs
branch
September 6, 2026 13:49
baozhoutao
pushed a commit
that referenced
this pull request
Sep 6, 2026
…vel anchors Second round of the scripts/** unresolvable-citation migration PR #16301 started. Two of the six held files freed since that PR landed -- check-docs-section-name.mjs and docs-audit/affected-docs.mjs (PR #16300), check-type-check-coverage.mjs (PR #16295) -- so their 7 citations migrate now by the same method: the file named as a file-level anchor, the number kept beside it as data, no digit repaired or repointed. - check-docs-section-name.mjs: concept.mdx:426, doc-pages.mdx:257 and forms.mdx:183 each resolve to exactly one tracked file under content/docs/** (forms.mdx is ambiguous by basename alone -- two files share it -- but only content/docs/ui/forms.mdx has a line 183 carrying the cited "sections": [/* ... */] shape). - check-type-check-coverage.mjs: engine.test.ts:2547/2577 resolves to packages/services/service-automation/src/engine.test.ts, named by the surrounding prose ("service-automation's note"). - docs-audit/affected-docs.mjs: three rest-server.ts citations resolve to packages/rest/src/rest-server.ts, the only tracked file of that name. The corpus residual (scripts/check-scripts-symbol-anchors.mjs --list-unresolvable) drops from 15 to 8, all 8 still held by open PRs (#16215, #16202) -- none an ambiguity. judgeUntrackedLineAnchors stays false per the #15809 fence (flips only at residual zero). Header prose updated to record both dated readings. Part of #15809. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #12511.
Seven of the card's eight residual packages now type-check their own tests through a sibling
test program named by their own
typecheckscript, so an error in a test file surfaces inseconds instead of only after a full-closure build.
@objectstack/http-conformanceisdeliberately left out — its hole needs a config-policy judgement that is the card's to make,
stated at the bottom.
Config only:
tsconfig.test.json(new, 7),package.jsonscripts(7),test-typecheck-debt.json(new, 7, measured), the
TEST_DEBTrows inscripts/check-type-check-coverage.mjs, the mergedispositions in
scripts/regen-artifacts.mjs, and a declared re-baseline inscripts/check-type-source-resolution.mjs. Nosrc/**and no test file is edited anywhere.The census — measured, with positive controls in the same run
Limb 2 is decided by RUNNING every config each package's
typecheckscript NAMES undertsc --noEmit --listFilesand counting that package's own test files in the resulting program —never by looking for a
tsconfig.test.jsonon disk. Taken at6a1e38244with the dependencyclosure built, and re-confirmed on the merged tree at
bb4ccec4e.typechecknamed BEFORE (files / ownsrc/ own tests)TEST_DEBTbeforemcptsconfig.json412 / 11 / 0 of 26formulatsconfig.json181 / 15 / 0 of 29platform-objectstsconfig.json419 / 91 / 0;tsconfig.scripts.json371 / 72 / 0 of 35connector-mcptsconfig.json349 / 4 / 0 of 3connector-openapitsconfig.json332 / 4 / 0 of 4connector-resttsconfig.json340 / 4 / 0 of 4service-smstsconfig.json751 / 7 / 0 of 5http-conformancetsconfig.json346 / 3 / 0 of 5Positive controls, same binary, same run, same worktree — without them every zero above is
unfalsifiable:
packages/resttsconfig.test.json186 test files in program;packages/metadata-coretsconfig.test.json15;packages/drivers/driver-memorytsconfig.json(no test exclusion) 44. Every program in the table also holds a non-zerocount of the package's own
srcfiles, so no zero is an empty-program artifact.The coverage gate's own summary line, before and after:
pnpm check:type-check-coverageexits 0 before and after;--self-testexits 0 (55 semantic +97 observation + 45 re-measure + 28 built-closure + 19 auto-lowering + 18 exit-code cases hold).
Not a blanket edit — where the per-package judgement actually diverged
Each config states its own reading in its own header. The two axes that mattered:
mcp"type": "module", so the inherited NodeNext already reads its tests as ESM and is the stricter of the two readings; measured, this layer writes zero extension-less relative imports andesnext/bundlersubtracts nothing.metadata-core's precedent, notrest's.lib: ["ES2022"]only.formulamodule: esnext/moduleResolution: bundler— the one package of the seven where the change subtracts a measured pile (TS1470 x2,import.metain a CJS program). Pluslib: ["ES2022"].platform-objectsTS2339onIntl.supportedValuesOfhere against an ES2020liband had to build a scratch config to see it). Itstypecheckgains a third leg beside the existingtsconfig.scripts.jsonone.connector-mcp,connector-openapi,connector-rest,service-smsimport.metaor an extension-less import gets no config-tier diagnostic ledgered as if it were a defect.rootDiris inherited untouched in all seven — every test file lives undersrc, and the twoimports that escape the package (
scripts/js-comment-mask.mjs, frommcpandplatform-objects)land on a checked-in
js-comment-mask.d.mts, so the raw programs carry noTS6059. Measured, notreasoned. Strictness is untouched everywhere, and no config declares
paths(a child'spathsreplaces the parent map rather than merging into it).
lib: ["ES2022"]has a measured effect of zero on today's tree in all seven — noTS2550either way. It is stated that way rather than claimed as a subtraction; it is fidelity to the Node
vitest actually runs on, and it is the exact trap the card was filed about (
Object.hasOwnisTS2550against a pre-ES2022 lib while the package's advertisedtypechecksays nothing).TEST_DEBTattribution — both directions, no remainderRAW is re-measured on the way out through the coverage gate's own
remeasureProjectshape(extends the package's
tsconfig.json, drops ONLY the test glob) at6a1e38244with the closurebuilt. RECORDED equalled RAW for all seven, class for class and file for file.
mcpformulaplatform-objectsconnector-mcpconnector-openapiconnector-restservice-smsThe single dissolution is
formula'sTS1470x2 undermodule: esnext. Nothing was exposedbehind it — there was no unresolved-import cascade to collapse in any of the seven, so there is
no
+nterm anywhere. Not one of the 83 is repaired here; this change edits no test file, and eachwould have been reported on
origin/mainhad these programs always existed.One composition correction the deleted
formulaentry earned: it attributed itsTS2591x6 toprocess. Measured, all six are node builtins named as bare specifiers (node:fsx2,node:pathx2,node:urlx2) and theTS2339x2 beside them readProperty 'url' does not exist on type 'ImportMeta'— one cause, this package declaring no@types/nodeand naming notypes. Real debt, now ledgered per file and per signature, anddeliberately not repaired here.
Two mechanical consequences, both recorded in place:
scripts/regen-artifacts.mjsgains sevenNOT_DRIVER_MANAGEDrows, one per new ledger.reconcileGeneratorskeys on (owner, script), so one row standing for the family would be adisposition nobody made for any of these files.
pnpm check:merge-driverexits 0.scripts/check-type-source-resolution.mjstakes the re-baseline its own doc-block opens forexactly this case, with the provenance the doc-block requires: every admitted dep is annotated
via tsconfig.test.jsonby the gate itself, i.e. reached only through the program this changeonboarded.
125 -> 132programs,61 -> 61entries,310 -> 319package-dep pairs(
mcp+2,platform-objects+3, the three connectors +1 each,service-sms+1).formulaonboarded a program and admitted nothing, which is the control saying the other sixreport a real widening rather than an artifact of the population growing.
pathsis measured tobe the wrong tool for the onboarding case (PR build(rest): give the package a test-layer tsc program and ledger its 37 errors #12570: 37 -> 42, billing other packages' source
diagnostics into the onboarding package's ledger), so the two places where a vitest alias and the
type program now disagree about which artifact they read are declared there rather than
papered over.
Positive control — the card's own claim, reproduced
One deliberate type error planted in an unledgered test file of a wired package, on the
committed tree, restored by blob hash. Nothing from this step is committed.
8 seconds on a shared box, naming the file. Before this change the same error was invisible to
that package's advertised
typecheckand reachable only through a full-closure build — the ~9minutes the card measured. Restore is
git checkout HEAD -- <path>(never a bare checkout, whichreads the index the mutation polluted), under a
trapwith absolute paths.Verification, pinned to
bb4ccec4etypecheck, both legs, on the merged tree with the closure built: 7 of7 exit 0, each printing
check:test-typecheck: OKwith its ledger held exactly(53 / 15 / 3 / 5 / 5 / 1 / 1 errors; 8 / 12 / 2 / 1 / 1 / 1 / 1 pinned signatures).
node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstackon the final tree: 70 commands, 70 run. Exit codes captured before any pipe.
67 exit 0 on the first pass. Three returned exit 3 —
PREREQUISITE NOT MET, which is NOTMEASURED and not a finding, never a red (
check:dual-build-cjs-loadsandcheck:i18nneed afull workspace build;
check:type-check-debtOOM'd under a 4096 MB ceiling the runner imposed,below the 6144 MB the CI job uses). Re-run with
pnpm builddone (exit 0) and at CI's ceiling,all three exit 0 — so 70 of 70 exit 0.
check:type-check-debt's own verdict line:check-type-check-coverage --re-measure: OK — 5 ledger entr(ies) re-measured in 95.9s, 55 raw tsc error(s) total, none above its recorded number.pnpm lintsweep and the full test farm are CI's.skip-changesetapplied: config-only, nothing is published from any package by this diff.What did NOT graduate, and why it is the card's call
@objectstack/http-conformancekeeps its entry. Its 2 recorded errors reproduce exactly(
TS2307x1,TS2304x1) and its own ledger note already says what they are — both insidenode_modules.d.tsfiles (@better-auth/core'sbun:sqliteimport,@better-fetch/fetch'sTimer), so the entry moves with the lockfile rather than with this package's code.The reason it cannot take the sibling route unchanged is a fact this repo had not recorded:
packages/qa/http-conformance/tsconfig.jsonis one of six package configs that do not extendthe repo root config, and it is the only one of those that also declares no
skipLibCheck— whichis the sole reason those two third-party declarations are checked at all. Both available repairs
depart from precedent:
.pnpmcontent-hash pathsthat move on any unrelated dependency bump — a ledger nobody can pay down, and red for reasons
that are about no test.
skipLibCheckon. None of the 31 sibling test configs declares it, and the alternative— putting it in the build config, or making that config extend the root like every other package —
changes what the build program reports for
srctoo, which every one of the 31 precedentsexplicitly refuses to do.
That is a judgement about this repo's config policy rather than about this package, so it is left
to the card rather than taken here.
Generated by Claude Code